package com.lanhe.common.utils.wechat;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.lanhe.common.constant.CacheConstants;
import com.lanhe.common.core.domain.wechat.WechatUser;
import com.lanhe.common.core.domain.wechat.WechatUserToken;
import com.lanhe.common.core.redis.RedisCache;
import com.lanhe.common.utils.StringUtils;
import com.lanhe.common.utils.http.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;


@Component
public class WechatUtil {
    private static final Logger log = LoggerFactory.getLogger(WechatUtil.class);

    @Value("${lanhe.wechat.appid}")
    private String appid;

    @Value("${lanhe.wechat.secret}")
    private String secret;

    @Autowired
    private RedisCache redisCache;

    /**获取openId**/
    private final static String JSCODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
    /**关于网页授权access_token和普通access_token的区别
     微信网页授权是通过OAuth2.0机制实现的，在用户授权给公众号后，公众号可以获取到一个网页授权特有的接口调用凭证（网页授权access_token），通过网页授权access_token可以进行授权后接口调用，如获取用户基本信息；
     其他微信接口，需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。*/
    /**普通token**/
    private final static String ORDINARY_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    /**获取授权token**/
    public final static String AUTHORIZE_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
    /**微信获取用户信息地址**/
    public final static String USER_INFO_URL = "https://api.weixin.qq.com/sns/userinfo";


    /**
     * 获取openId
     */
    public String getOpenId(String code) {
        String openId = "";
        log.info("入参:【{}】", code);
        try {
            String resp = HttpUtils.sendGet(JSCODE2SESSION_URL, "appid=" + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code");
            log.info("接口返回:【{}】", resp);
            JSONObject json = JSON.parseObject(resp);
            if (json.containsKey("openid")) {
                openId = json.getString("openid");
            }
        } catch (Exception e) {
            log.error("异常:{}", e);
            return openId;
        }
        return openId;
    }

    /**
     * 获取普通token
     */
    public String getToken() {
        String token = redisCache.getCacheObject(CacheConstants.WECHAT_TOKEN);
        if (StringUtils.isBlank(token)) {
            token = getTokenByHttp();
            // 保存时长是100分钟，微信token有效期2小时
            redisCache.setCacheObject(CacheConstants.WECHAT_TOKEN, token, CacheConstants.WECHAT_TOKEN_EXPIRATION, TimeUnit.MINUTES);
            return token;
        }
        return token;
    }



    /**
     * 获取token
     */
    public String getTokenByHttp() {
        String token = "";
        try {
            String resp = HttpUtils.sendGet(ORDINARY_TOKEN_URL, "grant_type=client_credential&appid=" + appid + "&secret=" + secret);
            log.info("接口返回:【{}】", resp);
            JSONObject json = JSON.parseObject(resp);
            if (json.containsKey("access_token")) {
                token = json.getString("access_token");
            } else {
                log.error("获取access_token失败:{}", json.toJSONString());
            }
        } catch (Exception e) {
            log.error("异常:{}", e);
            return token;
        }
        return token;
    }



    /**
     * @Description 根据code 获取网页授权access_token
     * @MethodName getAccessTokenBycode
     * @Param [code]
     * @ReturnType java.lang.StringBuilder
     * @Date  2023/12/1 17:06
     * @Author zxx
     * @Since 1.0
     */
    public WechatUserToken  getAccessTokenBycode(String code){
        WechatUserToken wechatUserToken = new WechatUserToken();

        try {
            String resp = HttpUtils.sendGet(AUTHORIZE_TOKEN_URL, "grant_type=authorization_code&appid=" + appid + "&secret=" + secret+ "&code=" + code);
            log.info("接口返回:【{}】", resp);
            JSONObject  json = JSON.parseObject(resp);
            if (json.containsKey("access_token")) {
                wechatUserToken.setOpenId(json.getString("openid"));
                wechatUserToken.setAccessToken(json.getString("access_token"));
            } else {
                log.error("获取access_token失败:{}", json.toJSONString());
            }
        } catch (Exception e) {
            log.error("异常:{}", e);
            return wechatUserToken;
        }
        return wechatUserToken;
    }

    /**
     * @Description 获取微信信息
     * @MethodName getUserInfo
     * @Param [accessToken, openid]
     * @ReturnType com.lanhe.common.core.domain.wechat.WechatUser
     * @Date  2023/12/1 16:28
     * @Author zxx
     * @Since 1.0
     */
    public  WechatUser getUserInfo(String accessToken,String openid) {
        WechatUser wechatUser = null;
        // 获取用户信息
        String resp = HttpUtils.sendGet(USER_INFO_URL, "lang=zh_CN&openid=" + openid + "&access_token=" + accessToken);
        log.info("接口返回:【{}】", resp);
        JSONObject jsonObject = JSON.parseObject(resp);
        if (null != jsonObject) {
            try {
                wechatUser = new WechatUser();
                // 用户的标识
                wechatUser.setOpenId(jsonObject.getString("openid"));
                wechatUser.setUnionId(jsonObject.getString("unionid"));
                 // 昵称
                wechatUser.setNickname(jsonObject.getString("nickname"));
                 //用户的性别（1是男性，2是女性，0是未知）
                wechatUser.setSex(jsonObject.getInteger("sex"));
                 //用户所在国家
                wechatUser.setCountry(jsonObject.getString("country"));
                 //用户所在省份
                wechatUser.setProvince(jsonObject.getString("province"));
                 //用户所在城市
                wechatUser.setCity(jsonObject.getString("city"));
                // 用户的语言，简体中文为zh_CN
                wechatUser.setLanguage(jsonObject.getString("language"));
                // 用户头像
                wechatUser.setHeadImgUrl(jsonObject.getString("headimgurl"));
            } catch (Exception e) {
                int errorCode = jsonObject.getInteger("errcode");
                String errorMsg = jsonObject.getString("errmsg");
                System.err.printf("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
                return null;
            }
        }
        return wechatUser;
    }



}

